package net.easyjava.third.letv;

import com.alibaba.fastjson.JSONObject;
import net.easyjava.third.letv.bean.LetvResult;
import net.easyjava.third.letv.bean.LetvUploadData;
import net.easyjava.third.letv.bean.LetvVideo;
import net.easyjava.third.letv.constants.LetvVideoConstants;
import net.easyjava.third.letv.util.LetvApiUtil;
import net.easyjava.tools.http.HttpTools;
import net.easyjava.tools.lang.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by wxnacy on 16/6/28.
 */
public class LetvVideoClient {
    private static Logger logger = LoggerFactory.getLogger(LetvVideoClient.class);
    private static Map<String,String> parameter;
    private static String userUnique;
    private static String secretKey;
    /**
     * 获取视频详情
     * @param videoId
     * @return
     * @throws Exception
     */
    public LetvVideo getVideo(String videoId) throws LetvException, IOException {
        parameter.put("api", LetvVideoConstants.VIDEO_GET_API);
        parameter.put("video_id",videoId);
        String sign = LetvApiUtil.generateSign(parameter, secretKey);
        parameter.put("sign",sign);
        LetvResult result = LetvApiUtil.getResult(LetvVideoConstants.API_URL,null,parameter);

        if(result.isError()){
            throw new LetvException("letv 获取视频详情失败 videoId:"+videoId);
        }
        logger.debug("letv 获取视频详情成功 videoId[{}]", videoId);
        LetvVideo video = JSONObject.parseObject(result.getData().toJSONString(),LetvVideo.class);
        if(video != null && video.isCanPlay()){
            video.setPlayUrl(String.format(LetvVideoConstants.VIDEO_PLAY_URL,userUnique,video.getVideoUnique()));
            if(video.isDownload()){
                String realUrl = getVideoRealUrl(videoId);
                video.setVideoUrl(realUrl);
            }
        }
        return video;
    }

    /**
     * 获取视频真实地址
     * @param videoId
     * @return
     * @throws LetvException
     * @throws IOException
     */
    public String getVideoRealUrl(String videoId) throws LetvException, IOException {
        parameter.put("api", LetvVideoConstants.VIDEO_DOWNLOAD_API);
        parameter.put("video_id",videoId);
        String sign = LetvApiUtil.generateSign(parameter, secretKey);
        parameter.put("sign",sign);
        LetvResult result = LetvApiUtil.getResult(LetvVideoConstants.API_URL,null,parameter);
        if(result.isError()){
            throw new LetvException("letv 获取视频真实地址失败 videoId:"+videoId);
        }

        JSONObject json = result.getData();
        logger.debug("letv 获取视频真实地址成功 videoId[{}]", videoId);
        return json.getString("download_url");
    }

    /**
     * 获取上传视频的中间件
     * @param videoName
     * @return
     * @throws LetvException
     * @throws IOException
     */
    public LetvUploadData getUploadUrl(String videoName,int isDownload) throws LetvException, IOException {
        parameter.put("api",LetvVideoConstants.VIDEO_UPLOAD_INIT_API);
        parameter.put("video_name", LetvApiUtil.encoder(videoName));
        parameter.put("isdownload", isDownload+"");

        String sign = LetvApiUtil.generateSign(parameter, secretKey);
        parameter.put("sign",sign);
        LetvResult result = LetvApiUtil.getResult(LetvVideoConstants.API_URL, null, parameter);

        if(result.isError()){
            throw new LetvException("letv 获取上传视频中间件失败 videoName:"+videoName);
        }
        logger.debug("letv 获取上传视频中间件成功 videoName[{}]", videoName);

        return JSONObject.parseObject(result.getData().toJSONString(), LetvUploadData.class);
    }

    /**
     * 通过文件上传视频 默认可下载
     * @param filePath
     * @return
     * @throws LetvException
     * @throws IOException
     */
    public LetvVideo uploadVideo(String filePath) throws LetvException, IOException {
        File file = new File(filePath);
        if (!file.exists() || !file.isFile()) {
            throw new FileNotFoundException("filepath can't found");
        }
        DataInputStream in = new DataInputStream(new FileInputStream(file));
        return uploadVideo(in, 1);
    }

    /**
     * 通过文件上传视频
     * @param filePath
     * @param isDownload
     * @return
     * @throws LetvException
     * @throws IOException
     */
    public LetvVideo uploadVideo(String filePath,int isDownload) throws LetvException, IOException {
        File file = new File(filePath);
        if (!file.exists() || !file.isFile()) {
            throw new FileNotFoundException("filepath can't found");
        }
        DataInputStream in = new DataInputStream(new FileInputStream(file));
        return uploadVideo(in, isDownload);
    }

    /**
     * 通过网络地址上传视频 默认可下载
     * @param url
     * @return
     * @throws LetvException
     * @throws IOException
     */
    public LetvVideo uploadVideoByUrl(String url) throws LetvException, IOException {
        if(StringTools.isEmpty(url)){
            throw new NullPointerException("url can't be empty");
        }
        InputStream in  = new URL(url).openStream();
        return uploadVideo(in, 1);
    }

    /**
     * 通过网络地址上传视频
     * @param url
     * @param isDownload
     * @return
     * @throws LetvException
     * @throws IOException
     */
    public LetvVideo uploadVideoByUrl(String url,int isDownload) throws LetvException, IOException {
        if(StringTools.isEmpty(url)){
            throw new NullPointerException("url can't be empty");
        }
        InputStream in  = new URL(url).openStream();
        return uploadVideo(in, isDownload);
    }

    /**
     * 上传视频
     * @param in 视频流
     * @return
     * @throws LetvException
     * @throws IOException
     */
    public LetvVideo uploadVideo(InputStream in,int isDownload) throws LetvException, IOException {
        LetvUploadData letvUploadData = getUploadUrl(System.currentTimeMillis() + StringTools.getRandom(5),isDownload);
        if(letvUploadData == null){
            throw new LetvException("letv 上传视频失败 ");
        }

        String uploadUrl = letvUploadData.getUploadUrl();
        String rtn = HttpTools.postUpload(uploadUrl, in, "video_file");
        LetvResult result = JSONObject.parseObject(rtn, LetvResult.class);

        if(result.isError()){
            throw new LetvException("letv 上传视频失败 videoId:"+letvUploadData.getVideoId());
        }
        logger.debug("letv 上传视频成功 videoId[{}]", letvUploadData.getVideoId());

        LetvVideo letvVideo = new LetvVideo();
        letvVideo.setVideoId(letvUploadData.getVideoId());
        letvVideo.setVideoUnique(letvUploadData.getVideoUnique());
//        LetvVideo letvVideo = getVideo(letvUploadData.getVideoId());
        return letvVideo;
    }



    /**
     * 构造单例
     */
    private volatile static LetvVideoClient singleton;
    private LetvVideoClient(final String userUnique,final String secretKey){
        this.userUnique = userUnique;
        this.secretKey = secretKey;
        init();

    }
    public static LetvVideoClient getInstance(final String userUnique,final String secretKey) {
        if (singleton == null) {
            synchronized (LetvVideoClient.class) {
                if (singleton == null) {
                    singleton = new LetvVideoClient(userUnique,secretKey);
                }
            }
        }
        if(parameter == null){
            init();
        }
        return singleton;
    }

    private static synchronized void init(){
        parameter = new HashMap<>();
        parameter.put("user_unique",userUnique);
        parameter.put("timestamp", System.currentTimeMillis() + "");
        parameter.put("format",LetvVideoConstants.FORMAT);
        parameter.put("ver",LetvVideoConstants.VER);
    }



    public static void main(String[] args) {
        LetvVideoClient client = LetvVideoClient.getInstance("eitmmd98tw","af7976083218b2e1ecb99772b3b34b11");
        try {
            System.out.println("client.videoGet(\"\") = " + client.getUploadUrl("冯巩&牛群-瞧这俩爹",1));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }



}
